package com.qhgrain.app.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.paas.base.modules.utils.lang.StringUtil;
import com.paas.base.modules.utils.page.PageBean;
import com.qhgrain.app.constant.UrlEnum;
import com.qhgrain.app.service.ApplicationService;
import com.qhgrain.app.service.MenuService;
import com.qhgrain.app.service.PermissionService;
import com.qhgrain.app.util.ConfigUtil;
import com.qhgrain.app.util.MenuTreeUtil;
import com.qhgrain.app.vo.MenuVo;
import com.qhgrain.app.vo.PairVo;
import com.qhgrain.app.vo.PermissionVo;
import com.qhgrain.gway.util.HttpUtil;

@Controller
@RequestMapping("/permission")
public class PermissionController {

	private static Logger LOG = LoggerFactory.getLogger(RoleController.class);
	@Autowired
	private ApplicationService applicationService;
	@Autowired
	private MenuService menuService;
	
	@Autowired
	private PermissionService permissionService;
	
	
	static String serverUrl = ConfigUtil
			.getProperties(UrlEnum.MENU_ROLE_PERMISSION)+"/permission";
	
	@RequestMapping(value="/list")
	public String list(Model model){
		//查询条件的所属应用需要填充
		model.addAttribute("appList",getAppList());
		return "permission/permission_list";
	}
	@RequestMapping(value="/list/table")
	public String queryPermissionForTable(Model model,String permissionName,String appId,String menuName,String pageNo,String pageSize){
		
		if(StringUtils.isEmpty(pageNo)){
			pageNo="1";
		}
		if(StringUtil.isBlank(pageSize)){
			pageSize = "10";
		}
		
		Map<String,Object> map = new HashMap<String,Object>();
		if(StringUtil.isNotBlank(appId)){
			map.put("appId", appId.trim());
			model.addAttribute("appId", appId.trim());
		}
		if(StringUtil.isNotBlank(permissionName)){
			map.put("name", permissionName.trim());
			model.addAttribute("permissionName", permissionName.trim());
		}
		if(StringUtil.isNotBlank(menuName)){
			map.put("menuName", menuName.trim());
			model.addAttribute("menuName", menuName.trim());
		}
		map.put("pageNo", pageNo);
		map.put("pageSize", pageSize);
		
		String requestVo;
		PageBean<Object> pageBean = new PageBean<Object>(Integer.parseInt(pageNo),Integer.parseInt(pageSize));;
		try {
			requestVo = HttpUtil.postFormParams(serverUrl, "/query/page", map);
			JSONObject voJson = JSONObject.parseObject(requestVo);
			
			if("1".equals(voJson.getString("state"))){
				JSONObject dataJson = voJson.getJSONObject("data");
				int count = dataJson.getIntValue("totalCount");
				JSONArray list = dataJson.getJSONArray("list");
				
				pageBean.setData(list);
				pageBean.setTotalCount(count);
				
			}else{
				LOG.error("权限分页查询，api失败。。。"+voJson);
			}
		} catch (Exception e) {
			LOG.error("权限分页查询出错。。。",e.getMessage());
		}
		model.addAttribute("pageBean", pageBean);
		model.addAttribute("appList",getAppList());
		return "permission/permission_list_table";
		
	}
	
	@RequiresPermissions({"common-service-permission:add"})
	@RequestMapping(value="/add")
	public String addPage(Model model){
		model.addAttribute("p", new JSONObject());
		model.addAttribute("appList", getAppList());
		return "permission/permission_edit";
	}
	
	@RequiresPermissions({"common-service-permission:edit"})
	@RequestMapping(value="/edit/{id}")
	public String editPage(Model model,@PathVariable String id){
		JSONObject permission = new JSONObject();
		try {
			String vo = HttpUtil.get(serverUrl+"/get/permission/"+id, new HashMap<String,String>());
			JSONObject voJson = JSONObject.parseObject(vo);
			if("1".equals(voJson.getString("state"))){
				permission = voJson.getJSONObject("data");
				if(StringUtil.isNotBlank(permission.getString("menuId"))){
					MenuVo m = this.menuService.get(permission.getString("menuId"));
					if(m != null){
						permission.put("menuName", m.getName());
					}
				}
			}else{
				LOG.error("获取权限信息，从api获取对象信息失败..."+voJson.getString("exceptionMsg"));
			}
			
		} catch (Exception e) {
			LOG.error("获取权限信息时失败...",e);
		}
		model.addAttribute("p", permission);
		model.addAttribute("appList",getAppList());
		return "permission/permission_edit";
	}
	
	
	@RequiresPermissions({"common-service-permission:add","common-service-permission:edit"})
	@RequestMapping(value="/save")
	@ResponseBody
	public JSONObject save(Model model,String permissionId,String permissionName,String description,
			String permissionType,String menuId,String pvalue,String oldPvalue){
		JSONObject result = new JSONObject();
		try {
			if(StringUtil.isBlank(permissionName) || StringUtil.isBlank(permissionType)
					|| StringUtil.isBlank(menuId) || StringUtil.isBlank(pvalue)){
				result.put("code", "fail");
				result.put("msg","权限名称或类型或所属菜单或权限值不能为空");
			}else{
				//再次校验权限值唯一
				boolean pvalueIsFit = true;
				if(!pvalue.equals(oldPvalue)){//说明pvalue是新的
					JSONObject json1 = findByPvalue(pvalue);
					if(!"notexist".equals(json1.getString("code"))){
						pvalueIsFit = false;
					}
				}
				if(!pvalueIsFit){
					result.put("code", "fail");
					result.put("msg", "权限值已存在，不能重复!");
					return result;
				}
				
				//再次确保菜单权限是唯一的
				if(StringUtil.isBlank(permissionId) && "0".equals(permissionType)){//菜单权限类型
					PermissionVo p = findMenuPermission(menuId);
					if(p != null){
						result.put("code", "fail");
						result.put("msg", "该菜单权限已存在，不能重复!");
						return result;
					}
				}
				String vo ;
				Map<String,Object> map = new HashMap<String,Object>();
				map.put("name", permissionName);
				map.put("type", permissionType);
				map.put("menuId", menuId);
				map.put("pvalue", pvalue);
				map.put("description", description);
				if(StringUtil.isBlank(permissionId)){
					//新增
					vo = HttpUtil.postFormParams(serverUrl, "/add", map);
				}else{
					//修改
					map.put("id", permissionId.trim());
					vo = HttpUtil.postFormParams(serverUrl, "/edit", map);
				}
				JSONObject voJson = JSONObject.parseObject(vo);
				if("1".equals(voJson.getString("state"))){
					result.put("code", "success");
					result.put("msg", "成功");
				}else{
					result.put("code", "fail");
					result.put("msg", "系统出错，操作失败!");
					LOG.error("保存角色,api失败..."+voJson);
				}
			}
		} catch (Exception e) {
			LOG.error("保存角色系统出错。。。"+e.getMessage());
		}
		return result;
	}
	
	@RequiresPermissions({"common-service-permission:delete"})
	@RequestMapping(value="/delete/{id}")
	@ResponseBody
	public JSONObject delete(Model model,@PathVariable String id){
		JSONObject result = new JSONObject();
		if(StringUtil.isBlank(id)){
			result.put("code", "0");
			result.put("msg", "权限id不能为空");
		}else{
			
			try {
				Map<String,Object> paramMap = new HashMap<String,Object>();
				paramMap.put("ids", id);
				String vo = HttpUtil.postFormParams(serverUrl, "/delete", paramMap);
				JSONObject voJson = JSONObject.parseObject(vo);
				if("1".equals(voJson.getString("state"))){
					result.put("code", "success");
					result.put("msg", "成功");
				}else{
					result.put("code", "fail");
					result.put("msg", "系统出错，删除失败!");
					LOG.error("删除权限,api失败..."+voJson);
				}
			} catch (Exception e) {
				LOG.error("删除权限，系统出错....",e.getStackTrace());
				result.put("code", "fail");
				result.put("msg", "系统出错");
			}
		}
		
		return result;
	}
	
	@RequestMapping(value="/get/role/count/{permissionId}")
	@ResponseBody
	public JSONObject getRoleCount(Model model,@PathVariable("permissionId")String permissionId){
		JSONObject result = new JSONObject();
		try {
			String vo = HttpUtil.get(serverUrl+"/query/roleids/"+permissionId, new HashMap<String,String>());
			JSONObject voJson = JSONObject.parseObject(vo);
			if("1".equals(voJson.getString("state"))){
				JSONArray list = voJson.getJSONArray("data");
				result.put("code", "success");
				result.put("count", list.size());
			}else{
				result.put("code", "fail");
				LOG.error("修改角色，从api获取对象信息失败..."+voJson.getString("exceptionMsg"));
			}
		} catch (Exception e) {
			result.put("code", "fail");
		}
		return result;
	}
	
	@RequestMapping(value="/check/pvalue")
	@ResponseBody
	public JSONObject checkPvalue(Model model,String pvalue){
		return findByPvalue(pvalue);
	}
	
	
	private JSONObject findByPvalue(String pvalue){
		JSONObject result = new JSONObject();
		try {
			if(StringUtil.isNotBlank(pvalue)){
				Map<String,Object> map = new HashMap<String,Object>();
				map.put("pvalue", pvalue);
				String restVo = HttpUtil.postFormParams(serverUrl, "/query/pvalue"	, map);
				JSONObject voJson = JSONObject.parseObject(restVo);
				if("1".equals(voJson.getString("state"))){
					if(StringUtil.isNotBlank(voJson.getString("data"))
							&& StringUtil.isNotBlank(JSONObject.parseObject(voJson.getString("data")).getString("id"))){
						result.put("code", "exist");
					}else{
						result.put("code", "notexist");
					}
				}else{
					LOG.error("菜单管理-》根据appId从api获取数据失败..."+restVo);
					result.put("code", "fail");
				}
			}else{
				result.put("code", "fail");
				result.put("msg", "权限值不能为空");
			}
			
		} catch (Exception e) {
			LOG.error("根据appId获取菜单报错。。。",e);
			result.put("code", "fail");
		}
		
		return result;
	}
	/**
	 * 根据菜单id获取它对于的菜单权限
	 * @param model
	 * @param menuId
	 * @return
	 */
	@RequestMapping(value="/find/menu/permission/{menuId}")
	@ResponseBody
	public JSONObject findMenuPermisson(Model model,@PathVariable("menuId")String menuId){
		JSONObject result = new JSONObject();
		if(StringUtil.isNotBlank(menuId)){
			try {
				PermissionVo  p = findMenuPermission(menuId);
				if(p != null){
					result.put("code", "yes");
					result.put("data", p);
				}else{
					result.put("code", "no");
				}
				
			} catch (Exception e) {
				LOG.error("根据菜单id获取其所有权限配置出错...",e);
				result.put("code", "no");
			}
		}else{
			result.put("code", "no");
		}
		
		return result;
	}
	
	private PermissionVo findMenuPermission(String menuId)throws Exception{
		JSONArray perArray = this.permissionService.queryByMenuIds(Arrays.asList(menuId));
		List<PermissionVo> permissions = JSONArray.parseArray(perArray.toJSONString(), PermissionVo.class);
		for(PermissionVo p : permissions){
			if("0".equals(p.getType())){
				return p;
			}
		}
		return null;
	}
	
	@RequestMapping(value="/query/menus/{appId}")
	@ResponseBody
	public JSONObject queryMenus(Model model,@PathVariable String appId){
		JSONObject result = new JSONObject();
		try {
			
			//如果是超级管理员，不需要传userId, 如果不是，则传userId
			//map.put("userId", "");
			//菜单状态，这里不需要传
			JSONArray menusArray = menuService.getAll(appId, null, "0");
			List<MenuVo> menus = JSONArray.parseArray(menusArray.toJSONString(), MenuVo.class);
			MenuTreeUtil.buildTree(menus, true, true);
			result.put("code", "success");
			result.put("data", menus);
			
		} catch (Exception e) {
			LOG.error("根据appId获取菜单报错。。。",e);
			result.put("code", "fail");
		}
		
		return result;
	}
	
	@RequestMapping(value="/query/menus2/{appId}")
	@ResponseBody
	public String queryMenus2(Model model,@PathVariable String appId){
		
		try {
			
			//如果是超级管理员，不需要传userId, 如果不是，则传userId
			//map.put("userId", "");
			//菜单状态，这里不需要传
			JSONArray menusArray = menuService.getAll(appId, null, "0");
			return menusArray.toJSONString();
			
		} catch (Exception e) {
			LOG.error("根据appId获取菜单报错。。。",e);
			return "";
		}
		
	}
	
	private List<PairVo> getAppList(){
		try {
			return applicationService.getAll(null);
		} catch (Exception e) {
			LOG.error("获取所有app时报错...",e);
			return new ArrayList<PairVo>();
		}
	}
}
